require 'find'
require 'getoptlong'


# Method to convert bytes human readable form
# - Accepts size in bytes
# - Returns Array holding new bytes and type
#   Type = blank for byte,
#          K for Kilobyte
#          M for Megabyte
#          G for Gigabyte
def convSize(bytes)
  type = ""                # Size type
  if bytes > 1024          # Change to kb if larger than 1024 bytes
    bytes = bytes / 1024.0
    type = "K"
    if bytes > 1024.0      # Change to MB if larger than 1024 k bytes
      bytes = bytes / 1024.0
      type = "M"
      if bytes > 1024.0    # Change to GB if larger than 1024 m bytes
        bytes = bytes / 1024.0
        type = "G"
      end
    end
  end
  [bytes, type]           # return array of bytes with type
end

# Method prints directory/file with size
def printPath(paths, prev)
  bytes, type = convSize(paths[prev])               # Convert size to human readable values
  puts (bytes.round(1)).to_s + type + "\t" + (FileTest.directory?(prev)? "<Dir>\t":"     \t") + prev   # print output
end

paths = Hash.new()
total_size = 0

prev = nil
# Go through each file and get all sizes
# Find does a top down traversal of all directories/files in the current directory
Find.find('.') do |path|
  top_item = path.split("/")[1]             # hash key made with top level item in root
  next if top_item == nil                   # skip if nil
  top_item = top_item

  # Print output for this element
  if paths[top_item] == nil                 # If nil, we have a new top_item element
    if prev != nil                          # If prev is not nil, We have an element to print
      printPath(paths, prev)                # Call print routine
    end
    paths[top_item] = 0                     # initialize new element
  end

  # If a file, add size
  unless FileTest.directory?(path)
    begin
      s = FileTest.size(path)
      paths[top_item] += s       # add size to top level item in root
      total_size  += s           # add size to root
    rescue
      # Do nothing
    end
  end

  prev = top_item    # Save old top_item as prev
end

# Print last element
if prev.nil?
  puts "No Directories"
else
  printPath(paths, prev)
end

bytes , type = convSize(total_size)
puts "\nTotal Size: " + (bytes.round(1)).to_s + type

